package com.charith;

import java.util.Random;

import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

public class BinarySearchTestTheories {
	
	Random random;
	
	@Before
	public void initialize(){
		random = new Random();
	}
	
	@Test
	public void testTheories(){
		int maxArraySize = 1000;
		int maxValue = 1000;
		int experiments = 1000;
		int[] array;
		int target;
		int returnValue;
		
		while(experiments-- > 0){
			array = BinarySearch.randomSortedArray(maxArraySize, maxValue);
			if(random.nextBoolean())
				target = array[random.nextInt(array.length)];
			else
				target = random.nextInt();
			returnValue = BinarySearch.binarySearch(array, target);
			assertTheory1(array, target, returnValue);
			assertTheory2(array, target, returnValue);
			assertTheory3(array, target, returnValue);
			assertTheory4(array, target, returnValue);
			assertTheory5(array, target);
		}
	}
	
	public void assertTheory1(int[] array, int target, int returnValue){
		if(returnValue == -1)
			assertFalse(arrayContainsTarget(array, target));			
	}
	
	public void assertTheory2(int[] array, int target, int returnValue){
		if(returnValue >= 0)
			assertEquals(target, array[returnValue]);
	}
	
	public void assertTheory3(int[] array, int target, int returnValue){
		if(!arrayContainsTarget(array, target))
			assertEquals(-1, returnValue);
	}
	
	public void assertTheory4(int[] array, int target, int returnValue){
		String testDataInfo = "Array="+printArray(array)+" target="+target+" returnValue="+returnValue;
		assertEquals(testDataInfo, getTargetPosition(array, target), returnValue);
	}
	
	public void assertTheory5(int[] array, int target){
		int numberOfComparisons = BinarySearch.binarySearchComparisonCount(array, target);
		assertTrue(numberOfComparisons <= (1 + (Math.log10(array.length)/Math.log10(2))));
	}

	public boolean arrayContainsTarget(int[] array, int target){
		return getTargetPosition(array, target) >= 0;
	}
	
	public int getTargetPosition(int[] array, int target){
		for(int i=0; i<array.length; i++){
			if(array[i] == target)
				return i;
		}
		return -1;
	}
	
	public String printArray(int[] array){
		String elements ="";
		for(int i=0 ;i<array.length; i++){
			elements += array[i] +" ";
		}
		return elements;
	}
	
}
